#include "pch.h"
#include "Button.h"
#include "WidgetImpl.h"
#include "WinException.h"

using namespace Gui;




Button::Button(Widget* parent, const std::wstring& className, const std::wstring& caption, math::int2 pos, math::int2 size, int style)
	: Widget(parent, className, pos, size, style | BS_NOTIFY )

	, clicked(m_clicked)
	, doubleClicked(m_doubleClicked)
	, gainedFocus(m_gainedFocus)
	, lostFocus(m_lostFocus)
{
	setText(caption);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

Button::~Button()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




math::int2 Button::optimalSize() const
{
	SIZE size;
	if(!Button_GetIdealSize(d->hWnd, &size))
		BOOSTEXT_THROW(WinApiException("Button_GetIdealSize(d->hWnd, &size) failed"));

	return math::int2(size.cx, size.cy);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

LRESULT Button::msgProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
	/**
	 * By design, a window defers WM_COMMAND messages to the control
	 * again, so the control can in turn react to the notifications
	 * and emit the right signal. This might seem stupid with windows
	 * messages, but makes sense, as now anyone just needs to connect
	 * to the signals of a button, instead of waiting for messages.
	 */
	switch(msg)
	{
	case WM_COMMAND:
		{
			if((HWND)lParam == d->hWnd)
			{
				switch(HIWORD(wParam))
				{
				case BN_CLICKED:
					m_clicked();
					break;
				case BN_DBLCLK:
					m_doubleClicked();
					break;
				case BN_SETFOCUS:
					m_gainedFocus();
					break;
				case BN_KILLFOCUS:
					m_lostFocus();
					break;
				}
			}

			return 0;
		}
	default:
		return Widget::msgProc(msg, wParam, lParam);
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
